import java.io.*;
import java.util.*;

class Main implements Runnable
{
	static String ReadLn(int maxLength)
	{  
        byte line[] = new byte [maxLength];
        int length = 0;
        int input = -1;
        try{
            while (length < maxLength){
                input = System.in.read();
                if ((input < 0) || (input == '\n')) break; 
                line [length++] += input;
            }

            if ((input < 0) && (length == 0)) return null;  
            return new String(line, 0, length);
        }catch (IOException e){
            return null;
        }
    }
	
	public static void main(String [] args)
	{
		Main work = new Main();
		
		work.run();
	}
	
	public void run()
	{
		new WheresWaldorf().run();
	}
}

class WheresWaldorf implements Runnable
{
	public void run()
	{
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		
		try 
		{
			// Read the first input, which represents the # of cases.
			int cases = Integer.parseInt(reader.readLine());
			
			for (int count = 0; count < cases; count++)
			{				
				reader.readLine();
				
				String [] rowsColumns = reader.readLine().split(" ");
				
				// Read the # of rows and columns and convert them.
				int row = Integer.parseInt(rowsColumns[0]); 
				int column = Integer.parseInt(rowsColumns[1]);
				
				// Create the array. Extra row and column for bound checking.
				String [][] wordGrid = new String[row + 2][column + 2];
				
				// Create boundary.
				createCheckBound(wordGrid);
				
				// Read the next row lines of words.
				for (int rowWords = 1; rowWords < row + 1; rowWords++)
				{
					String word = reader.readLine().toLowerCase();
					
					// Start at row 1 column 1 and finish at row - 1.
					fillArray(wordGrid, word, rowWords, 1, column);
				}
				
				// Read the # of dictionary words and convert it.
				int numOfDic = Integer.parseInt(reader.readLine());
				
				// Create a HashMap of dictionary word with value of row and column.
				HashMap<String, ArrayList<Integer>> dMap = new HashMap<String, ArrayList<Integer>>();
			
				// An array to hold dictionary words (used later to display results).
				ArrayList<String> dList = new ArrayList<String>();
				
				for (int counter = 0; counter < numOfDic; counter++)
				{
					String dictionary = reader.readLine().toLowerCase();
					
					dMap.put(dictionary, new ArrayList<Integer>());
				
					dList.add(dictionary);
				}
				
				// Commence search for Waldorf!
				wheresWaldorf(dMap, wordGrid);
				printResults(dMap, dList, count);
			}
		} 
		catch (IOException ex) 
		{
			ex.printStackTrace();
		}
	
	}
	
	void  wheresWaldorf(HashMap<String, ArrayList<Integer>> dMap, String [][] wordGrid)
	{
		// Perform a linear search through the array.
		for (int row = 1; row < wordGrid.length - 1; row++)
		{
			for (int column = 1; column < wordGrid[0].length - 1; column++)
			{
				// Determine if the letter matches the any of the dictionary words.
				String letter = wordGrid[row][column];
				
				Set set = dMap.entrySet();
				
				Iterator iter = set.iterator();
				
			    while(iter.hasNext())
			    {
			        Map.Entry me = (Map.Entry)iter.next();
			        
			        // Retrieve dictionary word from map.
			        String dWord = (String) me.getKey();
			        
			        if (dWord.charAt(0) == letter.charAt(0))
			        {
			        	// Check for word that letter in grid produces.
			        	
						boolean hLeft, hRight, vUp, vDown, dUpLeft, dUpRight, dDownLeft, dDownRight = false;
			        	
			        	// Approach horizontally to the left (r, c-1).
			        	hLeft = findWord(dWord, wordGrid, row, column, 0, -1);
			        	
			        	// Approach horizontally to the right (r, c+1).
			        	hRight = findWord(dWord, wordGrid, row, column, 0, 1);
			        	
			        	// Approach vertically up (r - 1, c).
			        	vUp = findWord(dWord, wordGrid, row, column, -1, 0);
			        	
			        	// Approach vertically down (r + 1, c).
			        	vDown = findWord(dWord, wordGrid, row, column, 1, 0);
			        	
			        	// Approach diagonally up left (r - 1, c - 1).
			        	dUpLeft = findWord(dWord, wordGrid, row, column, -1, -1);
			        	
			        	// Approach diagonally up right (r - 1, c + 1).
			        	dUpRight = findWord(dWord, wordGrid, row, column, -1, 1);
			        	
			        	// Approach diagonally down left (r + 1, c - 1).
			        	dDownLeft = findWord(dWord, wordGrid, row, column, 1, -1);
			        	
			        	// Approach diagonally down right (r + 1, c + 1).
			        	dDownRight = findWord(dWord, wordGrid, row, column, 1, 1);
			        	
			        	if (hLeft || hRight || vUp || vDown || dUpLeft || dUpRight || dDownLeft || dDownRight)
			        	{
			        		addRowColToWord(dMap, row, column, dWord);
			        	} 
			        }
			    }
			}
		}
	}
	
	/*
	 * 
	 */
	void printResults(HashMap<String, ArrayList<Integer>> dMap, ArrayList<String> dList, int count)
	{
		if (count >= 1)
		{
			System.out.println();
		}
		
		for (int index = 0; index < dList.size(); index++)
		{
			String word = dList.get(index);
			
			ArrayList<Integer> values = dMap.get(word);
		
			if (values != null)
			{
				int row = values.get(0);
				int column = values.get(1);
				
				System.out.println(row + " " + column);
			}
		}
	}
	
	/*
	 * Add row and column position as value of the dictionary word key. 
	 */
	void addRowColToWord(HashMap<String, ArrayList<Integer>> dMap, int row, int column, String dWord)
	{
		// Add row and column position as value of the dictionary word key.
		
		// Check that the value arrayList is empty.
		ArrayList<Integer> value = dMap.get(dWord);
		
		// For now ignore the cases.
		if (value.isEmpty())
		{
			// Add row and columns as values.
			value.add(row);
			value.add(column);
			
			// Map value array with key.
			dMap.put(dWord, value);
		}
	}
	
	
	/*
	 * Check cases if we found a dictionary word in grid more than once.
	 */
	boolean checkCases(int oldRowPos, int oldColPos, int newRowPos, int newColPos)
	{
		return false;
	}
	
	/*
	 * Used to check for word in a grid depending on delta row and delta column.
	 */
	boolean findWord(String word, String [][] wordGrid, int row, int column, int rowChange, int colChange)
	{
		int wordPos = 0;
		
		// Ignore the first character.
		word = word.substring(1);
		
		String letterValue = "";
		boolean done = false;		
	
		while (done == false)
		{
				int wRow = row + rowChange;
				int wCol = column + colChange;
				
				letterValue += wordGrid[wRow][wCol];
				
				if (wordPos < word.length())
				{
					if (letterValue.charAt(wordPos) != word.charAt(wordPos))
					{
						return false;
					} 
						wordPos++;
				}
				
				if (letterValue.length() == word.length())
				{
						return true;
				}
			
				row += rowChange;
				column += colChange;
		}

		return true;
	}
	
	/*
	 * Create a boundary around the array with nulls.
	 * Easier for checking if we are still inside array or not.
	 */
	void createCheckBound(String [][] arrayGrid)
	{
		for (int row = 0; row < arrayGrid.length; row++)
		{
			for (int column = 0; column < arrayGrid[0].length; column++)
			{
				// Fill top.
				if (row == 0 || row == arrayGrid.length - 1)
				{
					arrayGrid[row][column] = "?";
				} 
				else if (column == 0 || column == arrayGrid[0].length - 1)
				{
					arrayGrid[row][column] = "?";
				} 
			}
		}
	}
	
	/*
	 * Fill the array with word. 
	 */
	void fillArray(String[][] arrayGrid, String word, int sRowPos, int sColPos, int eColPos) 
	{
		int wordPosition = 0;
		
		// Row should stay constant.
		for (int col = sColPos; col < eColPos + 1; col++)
		{
			arrayGrid[sRowPos][col] = word.substring(wordPosition, wordPosition + 1);
			wordPosition++;
		}	
	}
}